﻿using System;
using System.ComponentModel;
using System.Xml;
using System.Xml.Serialization;

namespace LaunchPad.Core
{
    public class Product : INotifyPropertyChanged, IIdentifiable, INameable
    {
        private ProductCharacterization _characterization;
        private string _description;
        private Guid _id;
        private TimeSpan _leadIn;
        private TimeSpan _leadOut;
        private double _maxUses = double.PositiveInfinity;
        private string _name;
        private TimeSpan _timeToReset;

        public Product() : this(string.Empty)
        {
        }

        public Product(string name)
        {
            Name = name;
            _id = Guid.NewGuid();
            Characterization = new ProductCharacterization();
        }

        [XmlAttribute]
        public string Description
        {
            get { return _description; }
            set
            {
                if (_description != value)
                {
                    _description = value;
                    OnPropertyChanged("Description");
                }
            }
        }

        [XmlIgnore]
        public TimeSpan LeadIn
        {
            get { return _leadIn; }

            set
            {
                if (_leadIn != value)
                {
                    _leadIn = value;
                    OnPropertyChanged("LeadIn");
                }
            }
        }

        [XmlAttribute("LeadIn", DataType = "duration")]
        public string LeadInXml
        {
            get { return XmlConvert.ToString(LeadIn); }
            set { LeadIn = XmlConvert.ToTimeSpan(value); }
        }

        [XmlIgnore]
        public TimeSpan LeadOut
        {
            get { return _leadOut; }

            set
            {
                if (_leadOut != value)
                {
                    _leadOut = value;
                    OnPropertyChanged("LeadOut");
                }
            }
        }

        [XmlAttribute("LeadOut", DataType = "duration")]
        public string LeadOutXml
        {
            get { return XmlConvert.ToString(LeadOut); }
            set { LeadOut = XmlConvert.ToTimeSpan(value); }
        }

        [XmlAttribute]
        public double MaxUses
        {
            get { return _maxUses; }

            set
            {
                if (_maxUses != value)
                {
                    _maxUses = value;
                    OnPropertyChanged("MaxUses");
                }
            }
        }

        [XmlIgnore]
        public TimeSpan TimeToReset
        {
            get { return _timeToReset; }

            set
            {
                if (_timeToReset != value)
                {
                    _timeToReset = value;
                    OnPropertyChanged("TimeToReset");
                }
            }
        }

        public ProductCharacterization Characterization
        {
            get { return _characterization; }

            set
            {
                if (_characterization != value)
                {
                    _characterization = value;
                    OnPropertyChanged("Characterization");
                }
            }
        }

        [XmlAttribute("TimeToReset", DataType = "duration")]
        public string TimeToResetXml
        {
            get { return XmlConvert.ToString(TimeToReset); }
            set { TimeToReset = XmlConvert.ToTimeSpan(value); }
        }

        #region IIdentifiable Members

        [XmlAttribute]
        public Guid Id
        {
            get { return _id; }
            set
            {
                if (_id != value)
                {
                    _id = value;
                    OnPropertyChanged("Id");
                }
            }
        }

        #endregion

        #region INameable Members

        [XmlAttribute]
        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    OnPropertyChanged("Name");
                }
            }
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public EffectTrack CreateEffect()
        {
            return new EffectTrack(this);
        }

        protected void OnPropertyChanged(string property)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(property));
        }

        public override string ToString()
        {
            return Name;
        }

        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            if (obj is Product)
            {
                return Id == (obj as Product).Id;
            }
            return false;
        }
    }
}